#coding=utf-8

'''
@author: tongji
@contact: tongji@rekoo.com
'''
import sys
import time
import datetime
from farm_lib.models.game_info import GameInfo
from statistic_config import whitelist

import time
from django.conf import settings
from scribeutil import ScribeClient

def scribesender(host, port, category_prefix=None):
    scribe_client = ScribeClient(host, port)
    
    def sender(data):
        today = time.strftime('%Y-%m-%d')
        category = category_prefix + '_' + today if category_prefix else today
        scribe_client.log(category, data)
    return sender

output = scribesender(settings.SCRIBE_SERVER, settings.SCRIBE_PORT, settings.CATEGORY_PREFIX)

class StatisticsMiddleware(object):
    '''统计中间件'''
    def __init__(self):
        self.resetargs() # 重置中间数据
        self.resetdata() # 重置记录数据
        self.setoutput(output) # 将写入方式设置为UDP
        self.formatter = ['uid', 'scene', 'level', 'stay', 'action', 'v1', 'v2', 'v3', 'v4', 'num'] # 日志标准格式
        
        
    def process_request(self, request):
        return None
    
    def process_view(self, request, view_func, view_args, view_kwargs):
        self.resetdata() # 在执行视图函数之前先重置数据
        key = view_func.__module__ + '.' + view_func.__name__ # 全局名字
        
        if key in whitelist: #　如果在设置的白名单中，获取前后值，记录对应数据；否则不记录
            self.get_args(request, scene='before') # 获取视图执行之前的状态
            response = view_func(request, *view_args, **view_kwargs) # 执行视图函数
            self.get_args(request, scene='after') # 获取视图之后的状态
            self.statdata = self.basecallback(request, key) # 
            
            if self.statdata['success']: # 如果标志为True 则记录日志
                callback = whitelist.get(key, None) # 获取回调函数
                if callback:
                    try:
                        data = callback(request, self.args)
                    except Exception, e:
                        data = {'success':False}
                    self.statdata.update(data)
                
                if self.statdata['success']:
                    self.write()

            self.resetargs()
            return response
        return None
    
    def process_response(self, request, response):
        return response
    
    def get_args(self, request, scene=None):
        '''获取用户动作前后的一些数据，放在self.args中'''
        try:
            game_info = GameInfo.get(request.rk_user.uid)
            self.args[scene]['gold'] = game_info.gold
            self.args[scene]['points'] = game_info.points
            self.args[scene]['exp'] = game_info.exp
            self.args[scene]['level'] = game_info.level
            self.args[scene]['energy'] = game_info.energy
            self.args[scene]['co2'] = game_info.co2
            self.args[scene]['o2'] = game_info.o2
            self.args[scene]['unit_time_earnings'] = game_info.unit_time_earnings
            self.args[scene]['tax_building_total'] = game_info.tax_building_total
            self.args[scene]['invite_score'] = game_info.invite_score
            self.args[scene]['explore_total'] = game_info.explore_total
        except Exception, e:
            pass
    
    def basecallback(self, request, key):
        '''获取固定的数据，日志只是记录登陆用户的动作，如果没有登陆则标记此条日志为失败！！！'''
        try:
            rk_user = request.rk_user
            try:
                stay = (datetime.datetime.now() - rk_user.add_time).days +1
                stay = stay if stay < 4 else 0
            except:
                stay = 0
            data = {
                    'uid':rk_user.uid, 
                    'action':key, 
                    'ts':time.strftime('%H:%M:%S'), 
                    'scene':'k', 
                    'level':rk_user.game_info.level,
                    'stay':stay, 
                    'success':True, 
                    'num':1
                    }
        except Exception, e:
            data = {
                    'uid':-1, 
                    'action':key,  
                    'scene':'k', 
                    'level':-1,
                    'stay':-1, 
                    'success':True, 
                    'num':1
                    }            
        return data
    
    def format(self, data):
        '''格式化数据'''
        delimiter = '\t'
        record = []
        for item in self.formatter:
            record.append(data.get(item, ''))
        return delimiter.join(map(str, record))

    def write(self):
        '''将数据写到规定的渠道'''
        try:
            record = self.format(self.statdata)
        except Exception,e:
            print e
        else:
            self.output(record)
            
    def setoutput(self, output_handler = None):
        '''设置输出方式'''
        if output_handler:
            self.output = output_handler
        else:
            self.output = sys.stdout.write

    def resetdata(self):
        '''重置数据为空'''
        self.statdata = {}
    
    def resetargs(self):
        '''重置中间数据'''
        self.args = {'before':{}, 'after':{}}